package com.ib.algokit;

import java.io.IOException;

import org.activequant.broker.IBroker;
import org.activequant.calendar.NASDAQCalendarSettings;
import org.activequant.container.ITradeSystemContext;
import org.activequant.container.ITradeSystemContextThread;
import org.activequant.container.context.SpringTradeSystemContext;
import org.activequant.container.services.ITimeStampService;
import org.activequant.core.domainmodel.account.Account;
import org.activequant.core.domainmodel.account.BrokerAccount;
import org.activequant.core.domainmodel.data.Candle;
import org.activequant.core.domainmodel.data.Quote;
import org.activequant.core.domainmodel.data.TickerNews;
import org.activequant.core.domainmodel.data.TimeSeries;
import org.activequant.core.domainmodel.data.TradeIndication;
import org.activequant.core.domainmodel.marketdepth.MarketDepthEvent;
import org.activequant.core.domainmodel.marketscanner.MarketScan;
import org.activequant.core.domainmodel.marketscanner.ScanDataTimeSeries;
import org.activequant.core.types.TimeFrame;
import org.activequant.core.types.TimeStamp;
import org.activequant.core.util.TimeStampFormat;
import org.activequant.dao.IAccountDao;
import org.activequant.dao.IBalanceBookDao;
import org.activequant.dao.IBrokerAccountDao;
import org.activequant.dao.ICandleDao;
import org.activequant.dao.IMarketDepthEventDao;
import org.activequant.dao.IMarketScanDao;
import org.activequant.dao.IOrderBookDao;
import org.activequant.dao.IPortfolioDao;
import org.activequant.dao.IPositionDao;
import org.activequant.dao.IQuoteDao;
import org.activequant.dao.ISpecificationDao;
import org.activequant.dao.ITickerNewsDao;
import org.activequant.dao.ITradeIndicationDao;
import org.activequant.data.retrieval.ICandleSeriesSource;
import org.activequant.data.retrieval.ICandleSubscriptionSource;
import org.activequant.data.retrieval.IMarketDataReplayService;
import org.activequant.data.retrieval.IMarketDepthEventSeriesSource;
import org.activequant.data.retrieval.IMarketDepthEventSubscriptionSource;
import org.activequant.data.retrieval.IMarketScanSeriesSource;
import org.activequant.data.retrieval.IQuoteSeriesSource;
import org.activequant.data.retrieval.IQuoteSubscriptionSource;
import org.activequant.data.retrieval.IScanDataSeriesDataSource;
import org.activequant.data.retrieval.IScanSeriesDataIteratorSource;
import org.activequant.data.retrieval.ISeriesDataIteratorSource;
import org.activequant.data.retrieval.ISeriesDataSource;
import org.activequant.data.retrieval.ITickerNewsSeriesSource;
import org.activequant.data.retrieval.ITickerNewsSubscriptionSource;
import org.activequant.data.retrieval.ITradeIndicationSeriesSource;
import org.activequant.data.retrieval.ITradeIndicationSubscriptionSource;
import org.activequant.data.retrieval.dao.DaoCandleSeriesSource;
import org.activequant.data.retrieval.dao.DaoMarketDepthEventSeriesSource;
import org.activequant.data.retrieval.dao.DaoMarketScanSeriesSource;
import org.activequant.data.retrieval.dao.DaoQuoteSeriesSource;
import org.activequant.data.retrieval.dao.DaoTickerNewsSeriesSource;
import org.activequant.data.retrieval.dao.DaoTradeIndicationSeriesSource;
import org.activequant.data.util.MarketDataReplayService;
import org.activequant.data.util.series.ScanSeriesIteratorSplitFilter;
import org.activequant.data.util.series.ScanSeriesSourceToIteratorSourceAdapter;
import org.activequant.data.util.series.SeriesIteratorSplitFilter;
import org.activequant.data.util.series.SeriesSourceToIteratorSourceAdapter;
import org.activequant.tradesystem.ib.BacktestRunner;
import org.activequant.tradesystem.ib.IBPaperBroker;
import org.activequant.util.ib.IBTwsConnection;
import org.springframework.config.java.annotation.Bean;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.annotation.ExternalBean;

/**
 * Backtesting context, taking quote data from the database. TradeIndications are
 * simulated from the quotes using MIDPOINT strategy. 
 * <p>
 * Configuration annotated abstract class.<br/>
 * Holds the following associated variables:
 * <ul>
 * <li>format(TimeStampFormat)</li>
 * <li>START_DATE(String)</li>
 * <li>END_DATE(String)</li>
 * <li>SPLIT_TIME_FRAME(TimeFrame)</li>
 * <li>currentTimeStamp(AtomicReference&lt;TimeStamp&gt;)</li>
 * </ul>
 * <b>History:</b><br>
 *  - [16.12.2007] Created (Mike Kroutikov)<br>
 *
 *  @author Mike Kroutikov
 */
@Configuration
public abstract class BacktestDaoContextConfig {
	/**
	 * private final String IB_HOST     = "127.0.0.1";
	 */
	private final String IB_HOST     = "127.0.0.1";
	/**
	 * private final int    IB_PORT     = 7496;
	 */
	private final int    IB_PORT     = 7496;
	/**
	 * private final int    IB_CLIENTID = 0;
	 */
	private final int    IB_CLIENTID = 0;
	/**
	 * Bean<br/>
	 * Creates and returns an IBTwsConnection already connected to IB
	 * @return
	 */
	@Bean
	public IBTwsConnection ibConnection() {
		IBTwsConnection connection = new IBTwsConnection(IB_HOST, IB_PORT, IB_CLIENTID);
		//connection.connect();
		return connection;
	}
	/**
	 * private final TimeStampFormat format = new TimeStampFormat("yyyy/MM/dd HH:mm Z");
	 */
	private final TimeStampFormat format = new TimeStampFormat("yyyy/MM/dd HH:mm Z");
	
	private static boolean useEvaluationDates=true;
	
	public static String currentDate="2011/02/01";
	/**
	 * private final String START_DATE = "2011/02/04 09:30 "+NASDAQCalendarSettings.TimeZoneID;
	 */	
	public static String START_DATE = (useEvaluationDates?(currentDate+" 09:30 "):"2011/02/01 09:30 ")+NASDAQCalendarSettings.TimeZoneID;
	/**
	 * private final String END_DATE   = "2011/02/04 17:00 "+NASDAQCalendarSettings.TimeZoneID;
	 */
	public static String END_DATE   = (useEvaluationDates?(currentDate+" 17:00 "):"2011/02/01 17:00 ")+NASDAQCalendarSettings.TimeZoneID;
	/**
	 * private final TimeFrame SPLIT_TIME_FRAME = TimeFrame.hours(1);
	 */
	private final TimeFrame SPLIT_TIME_FRAME = TimeFrame.hours(8);
	/**
	 * private final AtomicReference&lt;TimeStamp&gt; currentTimeStamp = new AtomicReference&lt;TimeStamp&gt;();
	 */
//	private final AtomicReference<TimeStamp> currentTimeStamp = new AtomicReference<TimeStamp>();
	/**
	 * Bean<br/>
	 * Creates and returns a PaperBroker whose subscriptionSource(IQuoteSubscriptionSource) is set with the quoteSubscriptionSource Bean 
	 * (an IQuoteSubscriptionSource using the replayService Bean (MarketDataReplayService))
	 * @return
	 * @throws IOException
	 */
	@Bean
	public IBroker broker() throws IOException {
		BrokerAccount brokerAccount=account().getBrokerAccount("Interactive Brokers");
//		IBPaperBroker broker = new IBPaperBroker(timeStampService().currentTimeStamp(), orderBookDao(), portfolioDao(), positionDao(), balanceBookDao(), brokerAccount, quoteSubscriptionSource(),candleSubscriptionSource(),tradeIndicationSubscriptionSource());
		IBPaperBroker broker = new IBPaperBroker(timeStampService(), orderBookDao(), portfolioDao(), positionDao(), balanceBookDao(), brokerAccount, quoteSubscriptionSource(),candleSubscriptionSource(),tradeIndicationSubscriptionSource());	
		return broker;
	}
	@Bean
	public BrokerAccount brokerAccount() {
		BrokerAccount brokerAccount = brokerAccountDao().find(1L);
		if(brokerAccount==null){
			brokerAccount = new BrokerAccount("Interactive Brokers", "Dimitar Misev");			
			brokerAccount = brokerAccountDao().update(brokerAccount);
		}
		return brokerAccount;
	}
	@Bean
	public Account account() {
		accountDao().deleteAll();
		Account account = null;//accountDao().find(1L);
		if(account==null){
			account = new Account("Dimitar Misev");		
			account.addBrokerAccount(brokerAccount());
			account = accountDao().update(account);
		}
		return account;
	}
	/**
	 * ExternalBean<br/>
	 * protected abstract IAccountDao accountDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IAccountDao accountDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IBrokerAccountDao brokerAccountDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IBrokerAccountDao brokerAccountDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IOrderBookDao orderBookDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IOrderBookDao orderBookDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IPortfolioDao portfolioDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IPortfolioDao portfolioDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IPositionDao positionDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IPositionDao positionDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IBalanceBookDao balanceBookDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IBalanceBookDao balanceBookDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IQuoteDao quoteDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IQuoteDao quoteDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IMarketDepthEventDao marketDepthEventDao()
	 * @return
	 */
	@ExternalBean
	protected abstract IMarketDepthEventDao marketDepthEventDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract ITickerNewsDao tickerNewsDao()
	 * @return
	 */
	@ExternalBean
	protected abstract ITickerNewsDao tickerNewsDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract ITradeIndicationDao tradeIndicationDao();
	 * @return
	 */
	@ExternalBean
	protected abstract ITradeIndicationDao tradeIndicationDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract ICandleDao candleDao();
	 * @return
	 */
	@ExternalBean
	protected abstract ICandleDao candleDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract IMarketScanDao marketScanDao();
	 * @return
	 */
	@ExternalBean
	protected abstract IMarketScanDao marketScanDao();
	/**
	 * ExternalBean<br/>
	 * protected abstract ISpecificationDao specificationDao()
	 * @return
	 */
	@ExternalBean
	protected abstract ISpecificationDao specificationDao();
	/**
	 * Bean<br/>
	 * Creates and returns a DaoQuoteSeriesSource whose dao(IQuoteDao) is set with the quoteDao(IQuoteDao) Bean
	 * @return
	 * @throws IOException
	 */
	@Bean
	public IQuoteSeriesSource quoteSeriesSource() throws IOException {
		DaoQuoteSeriesSource source = new DaoQuoteSeriesSource();
		source.setDao(quoteDao());
		return source;
	}
	
	@Bean
	public ITradeIndicationSeriesSource tradeIndicationSeriesSource() throws IOException {
		DaoTradeIndicationSeriesSource source = new DaoTradeIndicationSeriesSource();
		source.setDao(tradeIndicationDao());
		return source;
	}
	
	@Bean
	public ICandleSeriesSource candleSeriesSource() throws IOException {
		DaoCandleSeriesSource source = new DaoCandleSeriesSource();
		source.setDao(candleDao());
		return source;
	}
	
	@Bean
	public IMarketDepthEventSeriesSource marketDepthEventSeriesSource() throws IOException {
		DaoMarketDepthEventSeriesSource source = new DaoMarketDepthEventSeriesSource();
		source.setDao(marketDepthEventDao());
		return source;
	}
	
	@Bean
	public ITickerNewsSeriesSource tickerNewsSeriesSource() throws IOException {
		DaoTickerNewsSeriesSource source = new DaoTickerNewsSeriesSource();
		source.setDao(tickerNewsDao());
		return source;
	}
	
	@Bean
	public IMarketScanSeriesSource marketScanSeriesSource() throws IOException {
		DaoMarketScanSeriesSource source = new DaoMarketScanSeriesSource();
		source.setDao(marketScanDao());
		return source;
	}
	
//	@Bean
//	public ITickerNewsSeriesSource tickerNewsSeriesSource() {
//		YahooTickerNewsSeriesSource source = new YahooTickerNewsSeriesSource();
//		return source;
//	}
	
	/**
	 * Bean<br/>
	 * Creates and returns a SeriesIteratorSplitFilter&gt;Quote&gt; whose job is to fetch and return Quotes (for some given SeriesSpecification) from the quoteSeriesSource Bean (DaoQuoteSeriesSource ), 
	 * fetching them in smaller chunks at a time, defined with the associated SPLIT_TIME_FRAME(TimeFrame) (TimeFrame.hours(1))
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	@Bean 
	protected ISeriesDataIteratorSource<Quote> quoteIteratorSource() throws IOException {
		SeriesSourceToIteratorSourceAdapter<Quote> quoteIterator = new SeriesSourceToIteratorSourceAdapter<Quote>();
		quoteIterator.setArrayDataSource((ISeriesDataSource<TimeSeries<Quote>>)(Object) quoteSeriesSource());
		SeriesIteratorSplitFilter<Quote> filter = new SeriesIteratorSplitFilter<Quote>();
		filter.setSeriesSource(quoteIterator);
		filter.setSplitTimeFrame(SPLIT_TIME_FRAME);
		return filter;
	}
	
	@SuppressWarnings("unchecked")
	@Bean 
	protected ISeriesDataIteratorSource<TradeIndication> tradeIndicationIteratorSource() throws IOException {
		SeriesSourceToIteratorSourceAdapter<TradeIndication> tradeIndicationIterator = new SeriesSourceToIteratorSourceAdapter<TradeIndication>();
		tradeIndicationIterator.setArrayDataSource((ISeriesDataSource<TimeSeries<TradeIndication>>)(Object) tradeIndicationSeriesSource());
		SeriesIteratorSplitFilter<TradeIndication> filter = new SeriesIteratorSplitFilter<TradeIndication>();
		filter.setSeriesSource(tradeIndicationIterator);
		filter.setSplitTimeFrame(SPLIT_TIME_FRAME);
		return filter;
	}
	
	@SuppressWarnings("unchecked")
	@Bean 
	protected ISeriesDataIteratorSource<Candle> candleIteratorSource() throws IOException {
		SeriesSourceToIteratorSourceAdapter<Candle> candleIterator = new SeriesSourceToIteratorSourceAdapter<Candle>();
		candleIterator.setArrayDataSource((ISeriesDataSource<TimeSeries<Candle>>)(Object) candleSeriesSource());
		SeriesIteratorSplitFilter<Candle> filter = new SeriesIteratorSplitFilter<Candle>();
		filter.setSeriesSource(candleIterator);
		filter.setSplitTimeFrame(SPLIT_TIME_FRAME);
		return filter;
	}
	
	@SuppressWarnings("unchecked")
	@Bean 
	protected ISeriesDataIteratorSource<MarketDepthEvent> marketDepthEventIteratorSource() throws IOException {
		SeriesSourceToIteratorSourceAdapter<MarketDepthEvent> marketDepthEventIterator = new SeriesSourceToIteratorSourceAdapter<MarketDepthEvent>();
		marketDepthEventIterator.setArrayDataSource((ISeriesDataSource<TimeSeries<MarketDepthEvent>>)(Object) marketDepthEventSeriesSource());
		SeriesIteratorSplitFilter<MarketDepthEvent> filter = new SeriesIteratorSplitFilter<MarketDepthEvent>();
		filter.setSeriesSource(marketDepthEventIterator);
		filter.setSplitTimeFrame(SPLIT_TIME_FRAME);
		return filter;
	}
	
	@SuppressWarnings("unchecked")
	@Bean 
	protected ISeriesDataIteratorSource<TickerNews> tickerNewsIteratorSource() throws IOException {
		SeriesSourceToIteratorSourceAdapter<TickerNews> tickerNewsIterator = new SeriesSourceToIteratorSourceAdapter<TickerNews>();
		tickerNewsIterator.setArrayDataSource((ISeriesDataSource<TimeSeries<TickerNews>>)(Object) tickerNewsSeriesSource());
		SeriesIteratorSplitFilter<TickerNews> filter = new SeriesIteratorSplitFilter<TickerNews>();
		filter.setSeriesSource(tickerNewsIterator);
		filter.setSplitTimeFrame(SPLIT_TIME_FRAME);
		return filter;
	}
	
	@SuppressWarnings("unchecked")
	@Bean 
	protected IScanSeriesDataIteratorSource<MarketScan> marketScanIteratorSource() throws IOException {
		ScanSeriesSourceToIteratorSourceAdapter<MarketScan> marketScanIterator = new ScanSeriesSourceToIteratorSourceAdapter<MarketScan>();
		marketScanIterator.setArrayDataSource((IScanDataSeriesDataSource<ScanDataTimeSeries<MarketScan>>)(Object) marketScanSeriesSource());
		ScanSeriesIteratorSplitFilter<MarketScan> filter = new ScanSeriesIteratorSplitFilter<MarketScan>();
		filter.setSeriesSource(marketScanIterator);
		filter.setSplitTimeFrame(SPLIT_TIME_FRAME);
		return filter;
	}
	
	/**
	 * Bean<br/>
	 * Creates and returns a MarketDataReplayService whose:<br/>
	 * startTimeStamp(TimeStamp)'s are set by parsing the associated START_DATE("2007/12/07")<br/>
	 * endTimeStamp(TimeStamp)'s are set by parsing the associated END_DATE("2007/12/09")<br/>
	 * seriesSource(ISeriesDataIteratorSource&lt;Quote&gt;) of its quoteReplay(ReplayServiceBase&lt;Quote&gt;) is set with the quoteIteratorSource Bean(a SeriesIteratorSplitFilter&gt;Quote&gt;)<br/>
	 * It also sets the value of the associated currentTimeStamp(AtomicReference&lt;TimeStamp&gt;) by parsing the associated START_DATE("2007/12/07")
	 * @return
	 * @throws IOException
	 */
	@Bean
	protected IMarketDataReplayService replayService() throws IOException {
		TimeStamp start = format.parse(START_DATE);
		TimeStamp end   = format.parse(END_DATE);
		if(start.isAfter(end)) {
			throw new IllegalStateException("start date must be BEFORE end date");
		}
//		currentTimeStamp.set(start);
		MarketDataReplayService replayService = new MarketDataReplayService();
		replayService.setStartTimeStamp(start);
		replayService.setEndTimeStamp(end);
		replayService.setQuoteSeriesDataSource(quoteIteratorSource());
		replayService.setTradeIndicationSeriesDataSource(tradeIndicationIteratorSource());
		replayService.setCandleSeriesDataSource(candleIteratorSource());
		replayService.setMarketDepthEventSeriesDataSource(marketDepthEventIteratorSource());
		replayService.setTickerNewsSeriesDataSource(tickerNewsIteratorSource());
		return replayService;
	}
	
//	@Bean
//	protected IScanDataReplayService scanReplayService() throws IOException {
//		TimeStamp start = format.parse(START_DATE);
//		TimeStamp end   = format.parse(END_DATE);
//		if(start.isAfter(end)) {
//			throw new IllegalStateException("start date must be BEFORE end date");
//		}
////		currentTimeStamp.set(start);
//		ScanDataReplayService replayService = new ScanDataReplayService();
//		replayService.setStartTimeStamp(start);
//		replayService.setEndTimeStamp(end);
//		replayService.setMarketScanSeriesDataSource(marketScanIteratorSource());
//		return replayService;
//	}
	/**
	 * Bean<br/>
	 * Creates and returns a BacktestRunner whose replayService(IMarketDataReplayService) is set with the replayService Bean (MarketDataReplayService)
	 * @return
	 * @throws IOException
	 */
	@Bean 
	public ITradeSystemContextThread main() throws IOException {
		return new BacktestRunner(replayService());
	}
	
	/**
	 * Bean<br/>
	 * Creates and returns a BacktestRunner whose replayService(IMarketDataReplayService) is set with the replayService Bean (MarketDataReplayService)
	 * @return
	 * @throws IOException
	 */
//	@Bean 
//	public ITradeSystemContextThread scanMain() throws IOException {
//		return new ScanBacktestRunner(scanReplayService());
//	}
	/**
	 * Bean<br/>
	 * Returns the IQuoteSubscriptionSource of the replayService Bean (MarketDataReplayService):<br/>
	 * Returns a new IQuoteSubscriptionSource which uses the quoteReplay(ReplayServiceBase&lt;Quote&gt;) of the MarketDataReplayService.
	 * @return
	 * @throws IOException
	 */
	@Bean
	public IQuoteSubscriptionSource quoteSubscriptionSource() throws IOException {
		return replayService().getQuoteSubscriptionSource();
	}
	/**
	 * Bean<br/>
	 * Creates and returns a QuoteToTradeIndicationSubscriptionSourceConverter whose quoteSource(IQuoteSubscriptionSource) and policy(Policy) are set
	 * with the quoteSubscriptionSource Bean (IQuoteSubscriptionSource) and Policy.MIDPOINT
	 * @return
	 * @throws IOException
	 */
	@Bean
	public ITradeIndicationSubscriptionSource tradeIndicationSubscriptionSource() throws IOException {
//		QuoteToTradeIndicationSubscriptionSourceConverter converter = new QuoteToTradeIndicationSubscriptionSourceConverter(quoteSubscriptionSource());
//		converter.setPolicy(QuoteToTradeIndicationSubscriptionSourceConverter.Policy.MIDPOINT);
//		return converter;
		return replayService().getTradeIndicationSubscriptionSource();
	}
	/**
	 * Bean<br/>
	 * Returns the ICandleSubscriptionSource of the replayService Bean (MarketDataReplayService):<br/>
	 * Returns a new ICandleSubscriptionSource which uses the candleReplay(ReplayServiceBase&lt;Candle&gt;) of the MarketDataReplayService.
	 * @return
	 * @throws IOException
	 */
	@Bean
	public ICandleSubscriptionSource candleSubscriptionSource() throws IOException {
		return replayService().getCandleSubscriptionSource();
	}
	/**
	 * Bean<br/>
	 * Returns the IMarketDepthEventSubscriptionSource of the replayService Bean (MarketDataReplayService):<br/>
	 * Returns a new IMarketDepthEventSubscriptionSource which uses the marketDepthEventReplay(ReplayServiceBase&lt;MarketDepthEvent&gt;) of the MarketDataReplayService.
	 * @return
	 * @throws IOException
	 */
	@Bean
	public IMarketDepthEventSubscriptionSource marketDepthEventSubscriptionSource() throws IOException {
		return replayService().getMarketDepthEventSubscriptionSource();
	}
	/**
	 * Bean<br/>
	 * Returns the ITickerNewsSubscriptionSource of the replayService Bean (MarketDataReplayService):<br/>
	 * Returns a new ITickerNewsSubscriptionSource which uses the tickerNewsReplay(ReplayServiceBase&lt;TickerNews&gt;) of the MarketDataReplayService.
	 * @return
	 * @throws IOException
	 */
	@Bean
	public ITickerNewsSubscriptionSource tickerNewsSubscriptionSource() throws IOException {
		return replayService().getTickerNewsSubscriptionSource();
	}
	
//	@Bean
//	public IMarketScanSubscriptionSource marketScanSubscriptionSource() throws IOException {
//		return scanReplayService().getMarketScanSubscriptionSource();
//	}
	/**
	 * Bean<br/>
	 * Creates and returns an ITimeStampService instance whose <code>currentTimeStamp()</code> method returns the value of the associated currentTimeStamp(AtomicReference&lt;TimeStamp&gt;)
	 * @return
	 */
	@Bean 
	public ITimeStampService timeStampService() {
		return new ITimeStampService() {
			public TimeStamp currentTimeStamp() {
				//return currentTimeStamp.get(); this was 
				try {
					return replayService().currentTimeStamp();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return null;
			}
		};
	}
	/**
	 * Bean<br/>
	 * Creates and returns a new SpringTradeSystemContext
	 * @return
	 */
	@Bean
	public ITradeSystemContext context() {
		return new SpringTradeSystemContext();
	}
}
